#include "stdio.h"

typedef struct _gdt_item_t
{
    unsigned short limit_low; // low 16 bits of segment limit
    unsigned int base_low: 24; // low 24 bits of segment base address
    unsigned char type: 4; // 段类型
    unsigned char segment : 1; // 1表示代码段或数据段，0表示系统段
    unsigned char DPL: 2; // 描述符特权登记
    unsigned char present: 1; // 存在位
    unsigned char limit_high: 4; // 段界限高4位
    unsigned char available: 1; // 系统保留位
    unsigned char long_mode: 1; // 64位扩展标志
    unsigned char big: 1; // 1表示段是64位段，0表示段是32位段
    unsigned char granularity: 1; // 粒度，0:1B 1：4KB
    unsigned char base_high; // 基址高8位
} __attribute__((packed)) gdt_item_t;

gdt_item_t gdt;

static void install_x64_code_descriptor()
{
    gdt_item_t *item = &gdt;
    item->limit_low = 0;
    item->base_low = 0;
    // 1000表示代码段
    item->type = 0b1000;
    // 1表示代码段或数据段，0表示系统段
    item->segment = 1;
    // 特权级暂时设置为0，最高级
    item->DPL = 0;
    // 敢不设置为1吗？
    item->present = 1;
    item->limit_high = 0;
    item->available = 0;
    item->long_mode = 1;
    // 这里为啥要设置为0，没搞懂
    item->big = 0;
    // 粒度是1B
    item->granularity =  0;
    item->base_high = 0;
}

void main(void)
{
    install_x64_code_descriptor();
    char* ptr = (char*) &gdt;
    for (int i = 0; i < 8; ++i) {
        printf("byte:%d is 0x%hhx\n", (i + 1), *ptr++);
    }
}